﻿//========================================================= 
/**@file LogCatHelper.h
 * @brief LogCat模块辅助接口
 * 
 * @date 2018-10-11   19:41:07
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_LOGCATHELPER_H_
#define _LIBZHOUYB_LOGCATHELPER_H_
//--------------------------------------------------------- 
#include "LogCat.h"

#include "appender/ConsoleAppender.h"
#include "appender/FolderAppender.h"
#include "appender/LogGroupAppender.h"
#include "appender/LoggerAdapterAppender.h"
#include "appender/LogExtension.h"

#include "layout/BasicLayout.h"
#include "layout/SimpleLayout.h"

#ifdef _MSC_VER
#include "../ability/logger/HwndLogger.h"
using zhou_yb::extension::ability::HwndLogger;
#endif

#ifdef __ANDROID__
#include "appender/AndroidLogcatAppender.h"
#endif
//--------------------------------------------------------- 
namespace zhou_yb {
namespace extension {
namespace logcat {
//--------------------------------------------------------- 
/**
 * @brief LogCat辅助接口
 * @date 2018-10-11 18:51:42
 */
class LogCatHelper
{
protected:
    LogCatHelper() {}
public:
    /// 在默认配置中添加新的appender
    template<class T>
    static Ref<T> DefaultAddNEW(const string& name, Ref<ILogLayout> layout = Ref<ILogLayout>(), LogLevel lv = LogAll)
    {
        LogCatLogger& _default = Default();
        if(!_default.Appender(name).IsNull())
            return Ref<T>();
        Ref<LogGroupAppender> grp;
        // 查找 LogGroupAppender
        Ref<ILogAppender> root = _default.Appender("");
        LogGroupAppender* pGrp = dynamic_cast<LogGroupAppender*>(&(*root));
        grp = (*pGrp);

        Ref<typename LogAsyncTraits<T>::Type> appender;
        // 为空则使用默认的 Layout
        if(layout.IsNull())
            layout = _default.Layout("");
        grp->add(_default.NewAppender<typename LogAsyncTraits<T>::Type>(name, appender, layout, lv));
        return appender;
    }
    /// 获取默认设置下的实例
    static LogCatLogger& Default()
    {
        LogCatLogger& _default = LogCatManager::Instance("");
        if(_default.IsEmpty())
        {
            Ref<BasicLayout> layout = _default.NewLayout<BasicLayout>("");
            Ref<LogGroupAppender> grp;
            _default.NewAppender<LogGroupAppender>("", grp);
            _default.NewLayout<NullLayout>("Null");

            #ifdef __ANDROID__
            LogCatHelper::DefaultAddNEW<AndroidLogcatAppender>("Android", layout);
            #else
            Ref<ConsoleAppender> console;
            grp->add(_default.NewAppender<ConsoleAppender>("Console", console, layout));
            #endif
        }
        return _default;
    }
    /**
     * @brief 将日志输出到目录中
     * @date 2019-08-01 23:04:07
     */
    static Ref<ILogAppender> DefaultWithFolder(const char* dir = "./log", const char* name = "LogCat", 
        size_t logCount = 4, size_t logMaxSize = FILE_M(8))
    {
        Ref<FolderAppender> folder = DefaultAddNEW<FolderAppender>("Folder");
        if(!folder.IsNull())
        {
            folder->Open(dir, name, logCount, logMaxSize);
        }
        return folder;
    }
    #ifdef _MSC_VER
    /**
     * @brief 添加对Hwnd的输出
     * @date 2018-10-11 19:48:47
     */
    static Ref<ILogAppender> DefaultWithHwnd(HWND hWnd, const char* name = "Hwnd")
    {
        LogCatLogger& _default = Default();
        typedef LoggerTAppender<HwndLogger> HwndAppender;
        const char LayoutName[] = "Simple";
        Ref<ILogLayout> layout = _default.Layout(LayoutName);
        if(layout.IsNull()) layout = _default.NewLayout<SimpleLayout>(LayoutName);
        Ref<HwndAppender> hwndAppender = DefaultAddNEW<HwndAppender>(name, layout);
        if(!hwndAppender.IsNull())
        {
            hwndAppender->Open(hWnd);
        }
        return hwndAppender;
    }
    #endif
};
//--------------------------------------------------------- 
/// 作用域触发器(析构时记录事件)
class LogCatScope
{
protected:
    LogCat* _log;
    string _name;
    Timer _timer;
    LogLevel _lv;
public:
    LogCatScope(LogCat& obj, LogLevel lv, const char* scopeName = NULL)
    {
        _log = &obj;
        _lv = lv;
        _name = _strput(scopeName);
        _log->message(_lv) << "---------------[" << _name << "]-[" << this << "]---------------";
        _timer.Restart();
    }
    ~LogCatScope()
    {
        Timer::TickType tick = _timer.Elapsed();
        _log->message(_lv) << "===============[" << _name << "]-[" << this << "]" << _right_width(tick, 13, '=') << "ms";
    }
};
//--------------------------------------------------------- 
/// 获取默认的LogCat对象
#ifndef LogCat_Default
#   define LogCat_Default(tag) LogCatHelper::Default().Get(LogCat::MacroTAG(__FILE__, tag))
#endif
/// 获取指定实例的LogCat对象
#ifndef LogCat_Instance
#   define LogCat_Instance(name, tag) LogCatManager::Instance(name).Get(LogCat::MacroTAG(__FILE__, tag))
#endif
/// 获取默认的作用域范围内定义
#ifndef LogCat_SCOPE
#define LogCat_SCOPE(name, scope, tag) \
    LogCat __logcat = LogCat_Instance(name, tag); \
    LogCatScope __logcat_scope(__logcat, LogLevel::LogDebug, scope)
#endif
//--------------------------------------------------------- 
} // namespace logcat
} // namespace extension
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_LOGCATHELPER_H_
//========================================================= 